﻿using System;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Common.Converters
{
    /// <summary>
    /// long类型JSON转换器（解决精度丢失问题）
    /// 将long序列化为字符串，反序列化时从字符串转回long
    /// </summary>
    public class LongJsonConverter : JsonConverter<long>
    {
        /// <summary>
        /// 序列化：将long转换为字符串
        /// </summary>
        public override void Write(Utf8JsonWriter writer, long value, JsonSerializerOptions options)
        {
            // 写入字符串形式的long值，避免前端精度丢失
            writer.WriteStringValue(value.ToString());
        }

        /// <summary>
        /// 反序列化：将字符串转换为long
        /// </summary>
        public override long Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            // 处理字符串类型的输入
            if (reader.TokenType == JsonTokenType.String)
            {
                var strValue = reader.GetString();
                if (long.TryParse(strValue, out long result))
                {
                    return result;
                }

                throw new JsonException($"无法将字符串 '{strValue}' 转换为 long 类型");
            }

            // 处理数字类型的输入（兼容直接传递数字的场景）
            if (reader.TokenType == JsonTokenType.Number)
            {
                // 检查是否在long范围内
                if (reader.TryGetInt64(out long result))
                {
                    return result;
                }

                throw new JsonException("数字超出 long 类型的取值范围");
            }

            // 不支持的类型
            throw new JsonException($"不支持的令牌类型 '{reader.TokenType}' 转换为 long");
        }
    }

    /// <summary>
    /// 可空long类型转换器（支持long?）
    /// </summary>
    public class NullableLongJsonConverter : JsonConverter<long?>
    {
        public override long? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            // 处理null值
            if (reader.TokenType == JsonTokenType.Null)
            {
                return null;
            }

            // 复用非空转换器的逻辑
            var converter = new LongJsonConverter();
            return converter.Read(ref reader, typeof(long), options);
        }

        public override void Write(Utf8JsonWriter writer, long? value, JsonSerializerOptions options)
        {
            if (value.HasValue)
            {
                // 有值时按long处理
                writer.WriteStringValue(value.Value.ToString());
            }
            else
            {
                // 空值写入null
                writer.WriteNullValue();
            }
        }
    }
}